{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 1. 获取数据\n",
    "# 2. 创建预测偏差\n",
    "# 3. 进行预测"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 1. 获取数据\n",
    "dtype = {'userId': np.int32, 'movieId': np.int32, 'rating': np.float32}\n",
    "df = pd.read_csv('../../../../../data/ml-latest-small/ratings.csv', usecols=range(3), dtype=dtype)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>userId</th>\n",
       "      <th>movieId</th>\n",
       "      <th>rating</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>6</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>47</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>50</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   userId  movieId  rating\n",
       "0       1        1     4.0\n",
       "1       1        3     4.0\n",
       "2       1        6     4.0\n",
       "3       1       47     5.0\n",
       "4       1       50     5.0"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>movieId</th>\n",
       "      <th>rating</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>list</th>\n",
       "      <th>list</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>userId</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>[1, 3, 6, 47, 50, 70, 101, 110, 151, 157, 163,...</td>\n",
       "      <td>[4.0, 4.0, 4.0, 5.0, 5.0, 3.0, 5.0, 4.0, 5.0, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>[318, 333, 1704, 3578, 6874, 8798, 46970, 4851...</td>\n",
       "      <td>[3.0, 4.0, 4.5, 4.0, 4.0, 3.5, 4.0, 4.0, 4.5, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>[31, 527, 647, 688, 720, 849, 914, 1093, 1124,...</td>\n",
       "      <td>[0.5, 0.5, 0.5, 0.5, 0.5, 5.0, 0.5, 0.5, 0.5, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>[21, 32, 45, 47, 52, 58, 106, 125, 126, 162, 1...</td>\n",
       "      <td>[3.0, 2.0, 3.0, 2.0, 3.0, 3.0, 4.0, 5.0, 1.0, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>[1, 21, 34, 36, 39, 50, 58, 110, 150, 153, 232...</td>\n",
       "      <td>[4.0, 4.0, 4.0, 4.0, 3.0, 4.0, 5.0, 4.0, 3.0, ...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                  movieId  \\\n",
       "                                                     list   \n",
       "userId                                                      \n",
       "1       [1, 3, 6, 47, 50, 70, 101, 110, 151, 157, 163,...   \n",
       "2       [318, 333, 1704, 3578, 6874, 8798, 46970, 4851...   \n",
       "3       [31, 527, 647, 688, 720, 849, 914, 1093, 1124,...   \n",
       "4       [21, 32, 45, 47, 52, 58, 106, 125, 126, 162, 1...   \n",
       "5       [1, 21, 34, 36, 39, 50, 58, 110, 150, 153, 232...   \n",
       "\n",
       "                                                   rating  \n",
       "                                                     list  \n",
       "userId                                                     \n",
       "1       [4.0, 4.0, 4.0, 5.0, 5.0, 3.0, 5.0, 4.0, 5.0, ...  \n",
       "2       [3.0, 4.0, 4.5, 4.0, 4.0, 3.5, 4.0, 4.0, 4.5, ...  \n",
       "3       [0.5, 0.5, 0.5, 0.5, 0.5, 5.0, 0.5, 0.5, 0.5, ...  \n",
       "4       [3.0, 2.0, 3.0, 2.0, 3.0, 3.0, 4.0, 5.0, 1.0, ...  \n",
       "5       [4.0, 4.0, 4.0, 4.0, 3.0, 4.0, 5.0, 4.0, 3.0, ...  "
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 2. 模型训练\n",
    "# 2.1 获取用户评分数据\n",
    "user_data = df.groupby('userId').agg([list])\n",
    "user_data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>userId</th>\n",
       "      <th>rating</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>list</th>\n",
       "      <th>list</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>movieId</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>[1, 5, 7, 15, 17, 18, 19, 21, 27, 31, 32, 33, ...</td>\n",
       "      <td>[4.0, 4.0, 4.5, 2.5, 4.5, 3.5, 4.0, 3.5, 3.0, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>[6, 8, 18, 19, 20, 21, 27, 51, 62, 68, 82, 91,...</td>\n",
       "      <td>[4.0, 4.0, 3.0, 3.0, 3.0, 3.5, 4.0, 4.5, 4.0, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>[1, 6, 19, 32, 42, 43, 44, 51, 58, 64, 68, 91,...</td>\n",
       "      <td>[4.0, 5.0, 3.0, 3.0, 4.0, 5.0, 3.0, 4.0, 3.0, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>[6, 14, 84, 162, 262, 411, 600]</td>\n",
       "      <td>[3.0, 3.0, 3.0, 3.0, 1.0, 2.0, 1.5]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>[6, 31, 43, 45, 58, 66, 68, 84, 103, 107, 111,...</td>\n",
       "      <td>[5.0, 3.0, 5.0, 3.0, 4.0, 4.0, 2.0, 3.0, 4.0, ...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                    userId  \\\n",
       "                                                      list   \n",
       "movieId                                                      \n",
       "1        [1, 5, 7, 15, 17, 18, 19, 21, 27, 31, 32, 33, ...   \n",
       "2        [6, 8, 18, 19, 20, 21, 27, 51, 62, 68, 82, 91,...   \n",
       "3        [1, 6, 19, 32, 42, 43, 44, 51, 58, 64, 68, 91,...   \n",
       "4                          [6, 14, 84, 162, 262, 411, 600]   \n",
       "5        [6, 31, 43, 45, 58, 66, 68, 84, 103, 107, 111,...   \n",
       "\n",
       "                                                    rating  \n",
       "                                                      list  \n",
       "movieId                                                     \n",
       "1        [4.0, 4.0, 4.5, 2.5, 4.5, 3.5, 4.0, 3.5, 3.0, ...  \n",
       "2        [4.0, 4.0, 3.0, 3.0, 3.0, 3.5, 4.0, 4.5, 4.0, ...  \n",
       "3        [4.0, 5.0, 3.0, 3.0, 4.0, 5.0, 3.0, 4.0, 3.0, ...  \n",
       "4                      [3.0, 3.0, 3.0, 3.0, 1.0, 2.0, 1.5]  \n",
       "5        [5.0, 3.0, 5.0, 3.0, 4.0, 4.0, 2.0, 3.0, 4.0, ...  "
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 2.2 获取电影数据\n",
    "movie_data = df.groupby('movieId').agg([list])\n",
    "movie_data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.5015569"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 2.3 获取所有电影平均评分\n",
    "global_rate = df.rating.mean()\n",
    "global_rate"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 随机梯度下降优化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 2.4 随机梯度下降优化\n",
    "bu = dict(zip(user_data.index, np.zeros(len(user_data.index))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# bu"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "bi = dict(zip(movie_data.index, np.zeros(len(movie_data.index))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "# bi"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(5):\n",
    "#     print(\"itear%d\", i)\n",
    "    for user_id, movie_id, real_rating in df.itertuples(index=False):\n",
    "        error = real_rating - (global_rate + bu[user_id] + bi[movie_id])\n",
    "        bu[user_id] += 0.1 * (error - 0.1 * bu[user_id])\n",
    "        bi[movie_id] += 0.1 * (error - 0.1 * bi[movie_id])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 创建预测方法\n",
    "def predict(u, i):\n",
    "    return global_rate + bu[u] + bi[i]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4.365151330491732"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 3. 进行预测\n",
    "predict(1, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "# bu"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "# bi"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>userId</th>\n",
       "      <th>movieId</th>\n",
       "      <th>rating</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>227</th>\n",
       "      <td>1.0</td>\n",
       "      <td>3744.0</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>228</th>\n",
       "      <td>1.0</td>\n",
       "      <td>3793.0</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>229</th>\n",
       "      <td>1.0</td>\n",
       "      <td>3809.0</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>230</th>\n",
       "      <td>1.0</td>\n",
       "      <td>4006.0</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>231</th>\n",
       "      <td>1.0</td>\n",
       "      <td>5060.0</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     userId  movieId  rating\n",
       "227     1.0   3744.0     4.0\n",
       "228     1.0   3793.0     5.0\n",
       "229     1.0   3809.0     4.0\n",
       "230     1.0   4006.0     4.0\n",
       "231     1.0   5060.0     5.0"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# df.groupby('userId').any()\n",
    "# np.unique(df.userId.values)\n",
    "df.where(df.userId==1).dropna().tail()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 数据分割方法\n",
    "def data_split(data_path, x=0.8, random=False):\n",
    "    \"\"\"\n",
    "    data_path: 数据文件路径\n",
    "    x: 测试集比例\n",
    "    random: 是否随机切分，默认是False\n",
    "    return: 返回的是训练集和测试集\n",
    "    \"\"\"\n",
    "    print(\"开始切分...\")\n",
    "    # 获取数据\n",
    "    dtype = {'userId': np.int32, 'movieId': np.int32, 'rating': np.float32}\n",
    "    data = pd.read_csv(data_path, usecols=range(3))\n",
    "    \n",
    "    # 获取用户的编号\n",
    "#     # 方法一: 将数据按userId进行分组,并获取用户的编号\n",
    "#     user_id = data.groupby('userId').any().index   \n",
    "    # 方法二: 获取用户的userId的Series，然后进行去重\n",
    "    user_ids = np.unique(data.userId.values)\n",
    "    # 方法三：\n",
    "#     user_ids = data.groupby('userId').agg([list]).index\n",
    "    \n",
    "    # 遍历user_id然后将每组用户的数据分为测试集和训练集\n",
    "    testset_index = []\n",
    "    for user_id in user_ids:\n",
    "        user_id_data = data.where(data.userId==user_id).dropna()\n",
    "        if random:\n",
    "            \"\"\"random==True，进行随机切分\"\"\"\n",
    "            # 因为不可变类型不可以被shuffle方法作用，所以强制转换为list类型\n",
    "            index = list(user_id_data.index)\n",
    "            np.random.shuffle(index)  # 打乱顺序\n",
    "            _index = round(len(index)*x)  # round方法返回的是传入参数的四舍五入的值\n",
    "            testset_index += index[_index:]\n",
    "        else:\n",
    "            \"\"\"random=False，不进行随机切分\"\"\"\n",
    "#             # 方法一：\n",
    "#             index = list(user_id_data.index)\n",
    "#             _index = round(len(user_id_data)*x)\n",
    "#             testset_index += index[_index:]\n",
    "            # 方法二\n",
    "            index = round(len(user_id_data)*x)\n",
    "            testset_index += list(user_id_data.index.values[index:])\n",
    "    \n",
    "    # 创建测试集和训练集\n",
    "    testset = data.loc[testset_index]\n",
    "    trainset = data.drop(testset_index)\n",
    "    \n",
    "    print(\"切分完成\")\n",
    "    \n",
    "    # 返回测试集和训练集\n",
    "    return trainset, testset\n",
    "    \n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "开始切分...\n",
      "切分完成\n"
     ]
    }
   ],
   "source": [
    "trainset, testset = data_split('../../../../../data/ml-latest-small/ratings.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>userId</th>\n",
       "      <th>movieId</th>\n",
       "      <th>rating</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>186</th>\n",
       "      <td>1</td>\n",
       "      <td>2899</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>187</th>\n",
       "      <td>1</td>\n",
       "      <td>2916</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>188</th>\n",
       "      <td>1</td>\n",
       "      <td>2944</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>189</th>\n",
       "      <td>1</td>\n",
       "      <td>2947</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>190</th>\n",
       "      <td>1</td>\n",
       "      <td>2948</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>100831</th>\n",
       "      <td>610</td>\n",
       "      <td>166534</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>100832</th>\n",
       "      <td>610</td>\n",
       "      <td>168248</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>100833</th>\n",
       "      <td>610</td>\n",
       "      <td>168250</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>100834</th>\n",
       "      <td>610</td>\n",
       "      <td>168252</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>100835</th>\n",
       "      <td>610</td>\n",
       "      <td>170875</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>20164 rows × 3 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "        userId  movieId  rating\n",
       "186          1     2899     5.0\n",
       "187          1     2916     4.0\n",
       "188          1     2944     5.0\n",
       "189          1     2947     5.0\n",
       "190          1     2948     5.0\n",
       "...        ...      ...     ...\n",
       "100831     610   166534     4.0\n",
       "100832     610   168248     5.0\n",
       "100833     610   168250     5.0\n",
       "100834     610   168252     5.0\n",
       "100835     610   170875     3.0\n",
       "\n",
       "[20164 rows x 3 columns]"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "testset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 数据分割方法\n",
    "def data_split2(data_path, x=0.8, random=False):\n",
    "    print(\"开始切分...\")\n",
    "    # 获取数据\n",
    "    dtype = {'userId': np.int32, 'movieId': np.int32, 'rating': np.float32}\n",
    "    data = pd.read_csv(data_path, usecols=range(3), dtype=dtype)\n",
    "    \n",
    "    # 获取data中的userId\n",
    "#     # 方法一：\n",
    "#     user_ids = data.groupby('userId').any().index\n",
    "    # 方法二：\n",
    "    user_ids = np.unique(data.userId.values)\n",
    "    \n",
    "    # 获取data中每个用户对应的行索引的测试集索引\n",
    "    testset_index = []\n",
    "    for user_id in user_ids:\n",
    "        # 获取包含当前用户的所有行索引\n",
    "        user_id_index = data.where(data.userId==user_id).dropna()\n",
    "        if random:\n",
    "            \"\"\"random==True, 进行随机划分\"\"\"\n",
    "            index = list(user_id_index.index)\n",
    "            np.random.shuffle(index)\n",
    "            _index = round(len(index)*x)\n",
    "            testset_index += index[_index:]\n",
    "        else:\n",
    "            \"\"\"random=False，不进行随机划分\"\"\"\n",
    "            # 方法一\n",
    "#             index = list(user_id_index.index)\n",
    "#             _index = round(len(index)*x)\n",
    "#             testset_index += index[_index:]\n",
    "            # 方法二\n",
    "            _index = round(len(user_id_index)*x)\n",
    "            testset_index += list(user_id_index.index.values[_index:])\n",
    "            \n",
    "    # 创建测试集和训练集\n",
    "    testset = data.loc[testset_index]\n",
    "    trainset = data.drop(testset_index)\n",
    "    \n",
    "    print(\"切割完成...\")\n",
    "    \n",
    "    # 返回训练集和测试集\n",
    "    return trainset, testset\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "开始切分...\n",
      "切割完成...\n"
     ]
    }
   ],
   "source": [
    "trainset, testset = data_split2(\"../../../../../data/ml-latest-small/ratings.csv\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "# trainset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "# testset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Int64Index([  1,   2,   3,   4,   5,   6,   7,   8,   9,  10,\n",
       "            ...\n",
       "            601, 602, 603, 604, 605, 606, 607, 608, 609, 610],\n",
       "           dtype='int64', name='userId', length=610)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby('userId').agg([list]).index"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 交替最小二乘法优化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>movieId</th>\n",
       "      <th>rating</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>list</th>\n",
       "      <th>list</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>userId</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>[1, 3, 6, 47, 50, 70, 101, 110, 151, 157, 163,...</td>\n",
       "      <td>[4.0, 4.0, 4.0, 5.0, 5.0, 3.0, 5.0, 4.0, 5.0, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>[318, 333, 1704, 3578, 6874, 8798, 46970, 4851...</td>\n",
       "      <td>[3.0, 4.0, 4.5, 4.0, 4.0, 3.5, 4.0, 4.0, 4.5, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>[31, 527, 647, 688, 720, 849, 914, 1093, 1124,...</td>\n",
       "      <td>[0.5, 0.5, 0.5, 0.5, 0.5, 5.0, 0.5, 0.5, 0.5, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>[21, 32, 45, 47, 52, 58, 106, 125, 126, 162, 1...</td>\n",
       "      <td>[3.0, 2.0, 3.0, 2.0, 3.0, 3.0, 4.0, 5.0, 1.0, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>[1, 21, 34, 36, 39, 50, 58, 110, 150, 153, 232...</td>\n",
       "      <td>[4.0, 4.0, 4.0, 4.0, 3.0, 4.0, 5.0, 4.0, 3.0, ...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                  movieId  \\\n",
       "                                                     list   \n",
       "userId                                                      \n",
       "1       [1, 3, 6, 47, 50, 70, 101, 110, 151, 157, 163,...   \n",
       "2       [318, 333, 1704, 3578, 6874, 8798, 46970, 4851...   \n",
       "3       [31, 527, 647, 688, 720, 849, 914, 1093, 1124,...   \n",
       "4       [21, 32, 45, 47, 52, 58, 106, 125, 126, 162, 1...   \n",
       "5       [1, 21, 34, 36, 39, 50, 58, 110, 150, 153, 232...   \n",
       "\n",
       "                                                   rating  \n",
       "                                                     list  \n",
       "userId                                                     \n",
       "1       [4.0, 4.0, 4.0, 5.0, 5.0, 3.0, 5.0, 4.0, 5.0, ...  \n",
       "2       [3.0, 4.0, 4.5, 4.0, 4.0, 3.5, 4.0, 4.0, 4.5, ...  \n",
       "3       [0.5, 0.5, 0.5, 0.5, 0.5, 5.0, 0.5, 0.5, 0.5, ...  \n",
       "4       [3.0, 2.0, 3.0, 2.0, 3.0, 3.0, 4.0, 5.0, 1.0, ...  \n",
       "5       [4.0, 4.0, 4.0, 4.0, 3.0, 4.0, 5.0, 4.0, 3.0, ...  "
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "user_rating = df.groupby('userId').agg([list])\n",
    "user_rating.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>userId</th>\n",
       "      <th>rating</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>list</th>\n",
       "      <th>list</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>movieId</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>[1, 5, 7, 15, 17, 18, 19, 21, 27, 31, 32, 33, ...</td>\n",
       "      <td>[4.0, 4.0, 4.5, 2.5, 4.5, 3.5, 4.0, 3.5, 3.0, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>[6, 8, 18, 19, 20, 21, 27, 51, 62, 68, 82, 91,...</td>\n",
       "      <td>[4.0, 4.0, 3.0, 3.0, 3.0, 3.5, 4.0, 4.5, 4.0, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>[1, 6, 19, 32, 42, 43, 44, 51, 58, 64, 68, 91,...</td>\n",
       "      <td>[4.0, 5.0, 3.0, 3.0, 4.0, 5.0, 3.0, 4.0, 3.0, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>[6, 14, 84, 162, 262, 411, 600]</td>\n",
       "      <td>[3.0, 3.0, 3.0, 3.0, 1.0, 2.0, 1.5]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>[6, 31, 43, 45, 58, 66, 68, 84, 103, 107, 111,...</td>\n",
       "      <td>[5.0, 3.0, 5.0, 3.0, 4.0, 4.0, 2.0, 3.0, 4.0, ...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                    userId  \\\n",
       "                                                      list   \n",
       "movieId                                                      \n",
       "1        [1, 5, 7, 15, 17, 18, 19, 21, 27, 31, 32, 33, ...   \n",
       "2        [6, 8, 18, 19, 20, 21, 27, 51, 62, 68, 82, 91,...   \n",
       "3        [1, 6, 19, 32, 42, 43, 44, 51, 58, 64, 68, 91,...   \n",
       "4                          [6, 14, 84, 162, 262, 411, 600]   \n",
       "5        [6, 31, 43, 45, 58, 66, 68, 84, 103, 107, 111,...   \n",
       "\n",
       "                                                    rating  \n",
       "                                                      list  \n",
       "movieId                                                     \n",
       "1        [4.0, 4.0, 4.5, 2.5, 4.5, 3.5, 4.0, 3.5, 3.0, ...  \n",
       "2        [4.0, 4.0, 3.0, 3.0, 3.0, 3.5, 4.0, 4.5, 4.0, ...  \n",
       "3        [4.0, 5.0, 3.0, 3.0, 4.0, 5.0, 3.0, 4.0, 3.0, ...  \n",
       "4                      [3.0, 3.0, 3.0, 3.0, 1.0, 2.0, 1.5]  \n",
       "5        [5.0, 3.0, 5.0, 3.0, 4.0, 4.0, 2.0, 3.0, 4.0, ...  "
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "movie_rating = df.groupby('movieId').agg([list])\n",
    "movie_rating.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [],
   "source": [
    "bu = dict(zip(user_rating.index, np.zeros(len(user_rating))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [],
   "source": [
    "bi = dict(zip(movie_rating.index, np.zeros(len(movie_rating))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [],
   "source": [
    "global_rate = df.rating.mean()\n",
    "# global_rate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练:0次\n",
      "训练:1次\n",
      "训练:2次\n",
      "训练:3次\n",
      "训练:4次\n",
      "训练:5次\n",
      "训练:6次\n",
      "训练:7次\n",
      "训练:8次\n",
      "训练:9次\n",
      "训练:10次\n",
      "训练:11次\n",
      "训练:12次\n",
      "训练:13次\n",
      "训练:14次\n"
     ]
    }
   ],
   "source": [
    "for i in range(15):\n",
    "    print(\"训练:%d次\" % i)\n",
    "    # 计算bu\n",
    "    for user_id, movieId_list, rating_list in user_rating.itertuples(index=True):\n",
    "        bu_up = 0\n",
    "#         print(type(movieId_list)\n",
    "        Ru = len(movieId_list)\n",
    "        bu_down = 0.01 + Ru\n",
    "        for movieId, rating in zip(movieId_list, rating_list):\n",
    "            bu_up += rating - global_rate - bi[movieId]\n",
    "        bu[user_id] = bu_up/bu_down\n",
    "    # 计算bi\n",
    "    \n",
    "    for movie_id, userId_list, rating_list in movie_rating.itertuples(index=True):\n",
    "        bi_up = 0\n",
    "        Ri = len(userId_list)\n",
    "        bi_down = 0.01 + Ru\n",
    "        for userId, rating in zip(userId_list, rating_list):\n",
    "            bi_up += rating - global_rate - bu[userId]\n",
    "        bi[movie_id] = bi_up/bi_down\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "# user_rating.loc[1, 'movieId'][0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'int'>\n",
      "<class 'list'>\n",
      "<class 'list'>\n"
     ]
    }
   ],
   "source": [
    "for x, y, z in user_rating[:1].itertuples(index=True):\n",
    "    print(type(x))\n",
    "    print(type(y))\n",
    "    print(type(z))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4.408620652616428"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict(1, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1: 0.8537873254283389,\n",
       " 2: 0.42518217522553065,\n",
       " 3: -1.0686845722627927,\n",
       " 4: 0.04181307454788895,\n",
       " 5: 0.11535808209531175,\n",
       " 6: -0.007552050277023941,\n",
       " 7: -0.2817673359744892,\n",
       " 8: 0.05742304926352167,\n",
       " 9: -0.24662607791980906,\n",
       " 10: -0.23254292735365967,\n",
       " 11: 0.2731377730713722,\n",
       " 12: 0.89336331757511,\n",
       " 13: 0.13618012963582818,\n",
       " 14: -0.11387313661846671,\n",
       " 15: -0.07427749521873481,\n",
       " 16: 0.18678451397508092,\n",
       " 17: 0.671645716351587,\n",
       " 18: 0.22096922190720436,\n",
       " 19: -0.8934053002237435,\n",
       " 20: 0.08900969323352458,\n",
       " 21: -0.24489924766577043,\n",
       " 22: -0.9469813151288582,\n",
       " 23: 0.12803781493279479,\n",
       " 24: 0.1314346441881678,\n",
       " 25: 1.2711671567897525,\n",
       " 26: -0.2753938445580389,\n",
       " 27: 0.03964574486785274,\n",
       " 28: -0.4901490826838267,\n",
       " 29: 0.6193980406411088,\n",
       " 30: 1.19123544879831,\n",
       " 31: 0.40774997454799605,\n",
       " 32: 0.243748714364088,\n",
       " 33: 0.27328296731344054,\n",
       " 34: -0.09130257358038397,\n",
       " 35: 0.5835288218592593,\n",
       " 36: -0.8754785773689012,\n",
       " 37: 0.6180830695782014,\n",
       " 38: -0.2906341916160213,\n",
       " 39: 0.47221202648119004,\n",
       " 40: 0.26551405136159384,\n",
       " 41: -0.2635836127240793,\n",
       " 42: 0.06244511086979205,\n",
       " 43: 1.0515280649276382,\n",
       " 44: -0.14644447167699984,\n",
       " 45: 0.36863115051515444,\n",
       " 46: 0.49335857967979674,\n",
       " 47: -0.4562749034767982,\n",
       " 48: 0.5245037016829608,\n",
       " 49: 0.717599637534278,\n",
       " 50: -0.7301810039592155,\n",
       " 51: 0.2728822347711524,\n",
       " 52: 0.9591311270576929,\n",
       " 53: 1.4981139306206164,\n",
       " 54: -0.5030182063442472,\n",
       " 55: -0.6662857521736016,\n",
       " 56: 0.2974202710911574,\n",
       " 57: -0.11459737306434398,\n",
       " 58: 0.3958261885722687,\n",
       " 59: 0.8375834560248752,\n",
       " 60: 0.20286948982875866,\n",
       " 61: 0.5169423478508035,\n",
       " 62: 0.5714822135322092,\n",
       " 63: 0.11226924056455588,\n",
       " 64: 0.25979971665854457,\n",
       " 65: 0.496460110638046,\n",
       " 66: 0.5074718148018708,\n",
       " 67: 0.42680823489172537,\n",
       " 68: -0.2703034974605093,\n",
       " 69: 0.839262148062402,\n",
       " 70: 0.7971248420624151,\n",
       " 71: 0.09285272749522644,\n",
       " 72: 0.6103992848337357,\n",
       " 73: 0.20384460870794466,\n",
       " 74: 0.7601266466061218,\n",
       " 75: -0.28779008056254407,\n",
       " 76: -0.44241806546182505,\n",
       " 77: 0.4571080139110424,\n",
       " 78: -0.35679843863238747,\n",
       " 79: 0.6805380247008286,\n",
       " 80: 0.7494021816324656,\n",
       " 81: -0.7545909729085271,\n",
       " 82: -0.12159915922012951,\n",
       " 83: -0.211416775702743,\n",
       " 84: 0.1786938705292005,\n",
       " 85: 0.1983880489973484,\n",
       " 86: 0.4011024957845311,\n",
       " 87: 0.44353938822832445,\n",
       " 88: 0.5092631466988636,\n",
       " 89: -0.030340696575965373,\n",
       " 90: 0.5659861720780279,\n",
       " 91: -0.11273556493167916,\n",
       " 92: 0.4371470045878706,\n",
       " 93: 0.7832958994156852,\n",
       " 94: -0.47120510318548675,\n",
       " 95: 0.5497024252767627,\n",
       " 96: 0.3637769635342316,\n",
       " 97: 0.6771141641085289,\n",
       " 98: 0.39572087488416074,\n",
       " 99: 0.3686833480445041,\n",
       " 100: 0.43727305851692844,\n",
       " 101: 0.05043680952282467,\n",
       " 102: -0.15247645100259136,\n",
       " 103: 0.3942794180341516,\n",
       " 104: 0.000759303502786295,\n",
       " 105: 0.607543816009206,\n",
       " 106: 0.9196206528612758,\n",
       " 107: 0.4078034787228021,\n",
       " 108: 0.4774858232294376,\n",
       " 109: -0.2868419716414336,\n",
       " 110: 0.1973566589880135,\n",
       " 111: -0.16305793374069744,\n",
       " 112: 0.06754650998514769,\n",
       " 113: 0.13841364046354554,\n",
       " 114: -0.08869662038563149,\n",
       " 115: 0.25548147150084244,\n",
       " 116: -0.07628245589423269,\n",
       " 117: -0.1649945887483231,\n",
       " 118: 0.2820963829511049,\n",
       " 119: 0.6673375772537355,\n",
       " 120: -0.10433881622795553,\n",
       " 121: -0.21881966936602548,\n",
       " 122: 1.0329220658577838,\n",
       " 123: 0.5041966077855083,\n",
       " 124: 0.45813820574858083,\n",
       " 125: 0.35047508825793394,\n",
       " 126: -0.2275940142211485,\n",
       " 127: -0.3972251321591858,\n",
       " 128: 0.8305514145736663,\n",
       " 129: 0.4104585525954772,\n",
       " 130: 0.028384334990258744,\n",
       " 131: -0.09948708639169725,\n",
       " 132: -0.47256821929586823,\n",
       " 133: -0.5326577851889301,\n",
       " 134: 0.06865357701695088,\n",
       " 135: 0.1212776440655616,\n",
       " 136: -0.18231655725350898,\n",
       " 137: 0.45102746903086954,\n",
       " 138: 0.02120078911801138,\n",
       " 139: -1.3606406683430845,\n",
       " 140: -0.008729858057149265,\n",
       " 141: 0.02015759157334592,\n",
       " 142: 0.2941955284482646,\n",
       " 143: -0.1835365383580387,\n",
       " 144: 0.11335869439556152,\n",
       " 145: -0.16648506686257944,\n",
       " 146: -0.3556704604684914,\n",
       " 147: -0.12118820617832046,\n",
       " 148: 0.21943149686979735,\n",
       " 149: -0.7841916340941508,\n",
       " 150: 0.0730664378187563,\n",
       " 151: 0.0464074684958423,\n",
       " 152: 0.48751081619373765,\n",
       " 153: -1.2943052054528645,\n",
       " 154: 0.8694468783566249,\n",
       " 155: 0.10266498219041911,\n",
       " 156: 0.1809995154300212,\n",
       " 157: -0.036105905032092676,\n",
       " 158: -0.07441909968222227,\n",
       " 159: -0.24304832727623604,\n",
       " 160: -0.7968492960758304,\n",
       " 161: 0.3233723581179082,\n",
       " 162: 0.7166104129043517,\n",
       " 163: -0.49909815409640246,\n",
       " 164: 0.7296274684351993,\n",
       " 165: 0.022132000036413826,\n",
       " 166: 0.5502710452088918,\n",
       " 167: -0.07751494431839606,\n",
       " 168: 0.9423387518898017,\n",
       " 169: 0.7440529339589188,\n",
       " 170: -0.1694440438767142,\n",
       " 171: 1.1095220310203373,\n",
       " 172: 0.30574622123699885,\n",
       " 173: -0.039083134795169366,\n",
       " 174: 0.15293780101980453,\n",
       " 175: 0.04065207643115805,\n",
       " 176: 0.5417738422331558,\n",
       " 177: -0.1295421999637894,\n",
       " 178: 0.5579641660111699,\n",
       " 179: 0.27593132328276054,\n",
       " 180: 0.028940645021595664,\n",
       " 181: -0.5613440944622811,\n",
       " 182: 0.005265986438953258,\n",
       " 183: 0.3062021483266124,\n",
       " 184: 0.2001090096615407,\n",
       " 185: 0.017595564932952723,\n",
       " 186: 0.5723195117031429,\n",
       " 187: 0.2587519292650446,\n",
       " 188: 0.8841154230875597,\n",
       " 189: 0.5347351882605346,\n",
       " 190: 0.3852012734704403,\n",
       " 191: 0.23103616167170876,\n",
       " 192: 0.5244605127164995,\n",
       " 193: 0.24607902350800176,\n",
       " 194: -0.027690801739063846,\n",
       " 195: 0.01457776412808138,\n",
       " 196: 0.4086159054760418,\n",
       " 197: 0.32612535099660206,\n",
       " 198: -0.02460497624558093,\n",
       " 199: -0.11699232732232585,\n",
       " 200: 0.30182908039645356,\n",
       " 201: 0.5887305398796048,\n",
       " 202: 0.3069905688651611,\n",
       " 203: 0.3228767395878818,\n",
       " 204: 0.4336202004923572,\n",
       " 205: 0.34396195872792135,\n",
       " 206: 0.5323948091432573,\n",
       " 207: -0.628288077902616,\n",
       " 208: -0.20736113043955065,\n",
       " 209: 0.7012348329950849,\n",
       " 210: 0.569865858317036,\n",
       " 211: 0.3782937507516091,\n",
       " 212: 0.07412886325933875,\n",
       " 213: 0.3162004565560896,\n",
       " 214: -0.6357273839859066,\n",
       " 215: 0.37825395368826237,\n",
       " 216: 0.1547879726155448,\n",
       " 217: -0.7398112421324655,\n",
       " 218: -0.14830672893348296,\n",
       " 219: -0.3408767235528245,\n",
       " 220: 0.4467194004224609,\n",
       " 221: 0.6123048919170789,\n",
       " 222: -0.344204445035766,\n",
       " 223: -0.25416620224613645,\n",
       " 224: 0.7378302096262069,\n",
       " 225: 0.14484248524454466,\n",
       " 226: -0.029213509275837324,\n",
       " 227: 0.6747936541749847,\n",
       " 228: 0.21122917496874302,\n",
       " 229: 0.2282420125922622,\n",
       " 230: -0.6485682722511358,\n",
       " 231: 0.29363945217804893,\n",
       " 232: -0.2531144343961647,\n",
       " 233: -0.22267146667990015,\n",
       " 234: 0.004383345641797468,\n",
       " 235: 0.13371601080189047,\n",
       " 236: 0.4601585249656017,\n",
       " 237: -0.15963501083289292,\n",
       " 238: 0.17246423922207577,\n",
       " 239: 0.5108869972696951,\n",
       " 240: 0.41689041809402355,\n",
       " 241: 0.4534629394455475,\n",
       " 242: 0.09010816081745253,\n",
       " 243: 0.6412767672143415,\n",
       " 244: 0.26062750135372964,\n",
       " 245: -0.7980385998116606,\n",
       " 246: 0.7393018904903113,\n",
       " 247: 0.2131241992428438,\n",
       " 248: 0.22726937146619444,\n",
       " 249: 0.19210887726194825,\n",
       " 250: 0.7135315560404701,\n",
       " 251: 1.303744716591546,\n",
       " 252: 0.6862384395419836,\n",
       " 253: 0.8407137443843046,\n",
       " 254: 0.45174850435344577,\n",
       " 255: -0.9425168823407183,\n",
       " 256: 0.4396333312745215,\n",
       " 257: -0.30692398626843015,\n",
       " 258: 0.6639638986665635,\n",
       " 259: -0.38887938647830683,\n",
       " 260: 0.24489334928973114,\n",
       " 261: 0.327990737139673,\n",
       " 262: -0.4080276469794771,\n",
       " 263: 0.20317960366743457,\n",
       " 264: 0.045365742013882555,\n",
       " 265: -0.16090218569466733,\n",
       " 266: -0.015968408699441175,\n",
       " 267: 0.6499357436299166,\n",
       " 268: -0.24257501066569206,\n",
       " 269: 0.11963066872126461,\n",
       " 270: -0.30047748149199927,\n",
       " 271: -0.32344846808984345,\n",
       " 272: 0.10595733748221631,\n",
       " 273: 0.4892901521617542,\n",
       " 274: -0.26721570974092895,\n",
       " 275: 0.5739179950235627,\n",
       " 276: 0.8841509465943898,\n",
       " 277: 0.07189365752380633,\n",
       " 278: 0.355319955341413,\n",
       " 279: 0.12511413833225932,\n",
       " 280: 0.3955402066423983,\n",
       " 281: -0.2933985931957417,\n",
       " 282: 0.5160858363544674,\n",
       " 283: -0.20696591250747223,\n",
       " 284: 0.21600169832439886,\n",
       " 285: 0.43586230847544155,\n",
       " 286: 0.26766733426282585,\n",
       " 287: -0.8891837406525748,\n",
       " 288: -0.35927695153251615,\n",
       " 289: 0.11795299089901352,\n",
       " 290: 0.6269380269152235,\n",
       " 291: 0.74101274311853,\n",
       " 292: -0.20537352358326671,\n",
       " 293: -0.887104716295075,\n",
       " 294: -0.8905041953338834,\n",
       " 295: 0.2098500220441834,\n",
       " 296: 0.6232346015266894,\n",
       " 297: -0.9105094158978912,\n",
       " 298: -1.1418872923999968,\n",
       " 299: 0.1428601914540255,\n",
       " 300: 0.7526630427923114,\n",
       " 301: -0.19799044046362876,\n",
       " 302: 0.47232810185608914,\n",
       " 303: 0.38676115283508045,\n",
       " 304: 0.35997015490302836,\n",
       " 305: 0.4148033915700698,\n",
       " 306: -0.18799275347980535,\n",
       " 307: -0.8390912541127731,\n",
       " 308: -1.0994570386152303,\n",
       " 309: 0.3196427558741741,\n",
       " 310: 0.02305583146471671,\n",
       " 311: -1.1699742396922672,\n",
       " 312: 0.19830917776978213,\n",
       " 313: -0.07752485546027475,\n",
       " 314: -0.46085230335018246,\n",
       " 315: -0.14807428892570035,\n",
       " 316: -0.5005080864972765,\n",
       " 317: 0.20751188932013107,\n",
       " 318: 0.2496547231518327,\n",
       " 319: 0.889288624705971,\n",
       " 320: 0.01904144604533274,\n",
       " 321: 0.07286846632885043,\n",
       " 322: -0.11584321097569303,\n",
       " 323: -0.3402394639616947,\n",
       " 324: -0.3694491277142598,\n",
       " 325: 0.03680844454992157,\n",
       " 326: 0.49791482338155507,\n",
       " 327: 0.5851455684621363,\n",
       " 328: -0.29659589773231826,\n",
       " 329: -0.6735965962971862,\n",
       " 330: 0.1716619433833957,\n",
       " 331: 0.11460460688420791,\n",
       " 332: 0.08247497646513044,\n",
       " 333: -0.8598772936603629,\n",
       " 334: -0.10190104880653823,\n",
       " 335: 0.14750082597579595,\n",
       " 336: 0.785879366328267,\n",
       " 337: 0.7013776167710923,\n",
       " 338: -0.5936530610909846,\n",
       " 339: 0.5559023927908063,\n",
       " 340: 0.6951161308984434,\n",
       " 341: 0.29419129505555336,\n",
       " 342: -0.5599962038915361,\n",
       " 343: 0.5197752325245053,\n",
       " 344: 0.24739695775105108,\n",
       " 345: 0.39762821078128724,\n",
       " 346: 0.16790772195229722,\n",
       " 347: 0.05069100685686339,\n",
       " 348: 1.1323879783423112,\n",
       " 349: 0.214896177828964,\n",
       " 350: -0.2569310336320929,\n",
       " 351: 0.15315410008827313,\n",
       " 352: 0.27007429149748263,\n",
       " 353: -0.013967526470107407,\n",
       " 354: 0.22075880457767086,\n",
       " 355: 0.38383734096602085,\n",
       " 356: 0.506852169592808,\n",
       " 357: 0.4437936238476367,\n",
       " 358: -0.2477732927159273,\n",
       " 359: -0.09717871149044677,\n",
       " 360: -0.13773969411526593,\n",
       " 361: -0.3310674304440143,\n",
       " 362: 0.7147469671482299,\n",
       " 363: -0.23481534721950476,\n",
       " 364: 0.673310731547954,\n",
       " 365: -0.7592580464833437,\n",
       " 366: 0.4172423221746115,\n",
       " 367: 0.3489451418854227,\n",
       " 368: -0.6625849142977681,\n",
       " 369: -0.11937578682501106,\n",
       " 370: 0.01685462061853822,\n",
       " 371: 1.0353954232439648,\n",
       " 372: -0.16054857596181105,\n",
       " 373: -0.3159905499868739,\n",
       " 374: 0.12006510904114366,\n",
       " 375: 0.3943886949966336,\n",
       " 376: 0.5450490325022019,\n",
       " 377: 0.4089136294443097,\n",
       " 378: 0.4624474565049679,\n",
       " 379: -0.1284260337040973,\n",
       " 380: 0.1701098268268948,\n",
       " 381: 0.0361089554863681,\n",
       " 382: 0.0017734328544415224,\n",
       " 383: 0.28443614287245084,\n",
       " 384: -0.4210560966882367,\n",
       " 385: -0.11118269539123829,\n",
       " 386: -0.7580979750245637,\n",
       " 387: -0.24810386443799787,\n",
       " 388: 0.11407397534353299,\n",
       " 389: 0.6172174271775803,\n",
       " 390: 0.3236029795172252,\n",
       " 391: 0.20040494779235232,\n",
       " 392: -0.31008338328912616,\n",
       " 393: 0.32357099709370946,\n",
       " 394: -0.5547342195328681,\n",
       " 395: -0.45111151606174343,\n",
       " 396: -0.3759877946554425,\n",
       " 397: 0.44786030086225226,\n",
       " 398: 0.7309706072024991,\n",
       " 399: 0.3881595221496918,\n",
       " 400: 0.9543222984796338,\n",
       " 401: 0.013416261660304532,\n",
       " 402: 0.3464182797536083,\n",
       " 403: 0.24520467511826138,\n",
       " 404: -0.11403578656024736,\n",
       " 405: 0.4939537088574688,\n",
       " 406: -0.24676843179915958,\n",
       " 407: 0.5655398533157334,\n",
       " 408: 0.5811036639414109,\n",
       " 409: 0.32681193163554384,\n",
       " 410: 0.5488689354899106,\n",
       " 411: -0.24635828165160684,\n",
       " 412: 0.3753782676026352,\n",
       " 413: 0.8837768677632517,\n",
       " 414: -0.1108726137940877,\n",
       " 415: 0.5564427142866171,\n",
       " 416: -0.4645442865508188,\n",
       " 417: 0.9252209660370876,\n",
       " 418: 0.11763465744135936,\n",
       " 419: 0.28848006463133297,\n",
       " 420: 0.30456792596586185,\n",
       " 421: 0.5834227458839838,\n",
       " 422: -0.18834779919428904,\n",
       " 423: 0.18285731701550872,\n",
       " 424: 0.15466933254527765,\n",
       " 425: 0.020232372140128338,\n",
       " 426: 0.16329898573312554,\n",
       " 427: -0.40651817608349655,\n",
       " 428: -0.8651303456005569,\n",
       " 429: 0.4865479219194479,\n",
       " 430: 0.22560510192698488,\n",
       " 431: -0.7720202136260789,\n",
       " 432: 0.1327015418026632,\n",
       " 433: 0.21525177993378397,\n",
       " 434: 0.2616318042027803,\n",
       " 435: 0.7956771256714771,\n",
       " 436: -0.32321694055226846,\n",
       " 437: 0.2879274166192677,\n",
       " 438: -0.14711461070094137,\n",
       " 439: 0.5630081733539671,\n",
       " 440: 0.3811485878025964,\n",
       " 441: 0.9913576401679638,\n",
       " 442: -2.2253040624770435,\n",
       " 443: 0.5743431790579028,\n",
       " 444: 0.2907129660514353,\n",
       " 445: 0.32136973565501165,\n",
       " 446: -0.29309896352935644,\n",
       " 447: 0.365970534547845,\n",
       " 448: -0.6547064220866503,\n",
       " 449: -0.23650449403344512,\n",
       " 450: 0.4863812358836632,\n",
       " 451: 0.2860150987778981,\n",
       " 452: 1.0462383469151897,\n",
       " 453: 0.43370140892205233,\n",
       " 454: 0.24675545158825882,\n",
       " 455: -0.0584464096733803,\n",
       " 456: 0.31436954886617774,\n",
       " 457: -0.05130426744430069,\n",
       " 458: 0.6467287955718959,\n",
       " 459: 0.8205347381709087,\n",
       " 460: 0.6767255832299199,\n",
       " 461: -0.6018576793675777,\n",
       " 462: -0.10531403926776677,\n",
       " 463: 0.26865682447055433,\n",
       " 464: 0.23458186078785262,\n",
       " 465: 0.6415190686576435,\n",
       " 466: 0.4148498702756856,\n",
       " 467: -0.10484659242564999,\n",
       " 468: -0.11521225808171812,\n",
       " 469: 0.16241856721866452,\n",
       " 470: 0.003761149922865476,\n",
       " 471: 0.33411958059277663,\n",
       " 472: 0.5907466193234661,\n",
       " 473: -0.09458105736758982,\n",
       " 474: -0.10560376644350976,\n",
       " 475: 0.9015633781780454,\n",
       " 476: 0.1706388873066441,\n",
       " 477: 0.2297958190554608,\n",
       " 478: -0.6850036873362626,\n",
       " 479: -0.18391683750149196,\n",
       " 480: -0.230967662882327,\n",
       " 481: -0.6924424874655141,\n",
       " 482: -0.09697943626213101,\n",
       " 483: 0.112431539833736,\n",
       " 484: 0.30988202496738765,\n",
       " 485: 0.3574428083361883,\n",
       " 486: 0.5074666627526482,\n",
       " 487: -0.3900018196464753,\n",
       " 488: 0.3620504556503479,\n",
       " 489: -0.4869031046062432,\n",
       " 490: -0.35544890713748317,\n",
       " 491: 0.651226134913137,\n",
       " 492: 0.3685173280835962,\n",
       " 493: 0.16642048141808688,\n",
       " 494: 0.6802122749469269,\n",
       " 495: 0.5026657766231153,\n",
       " 496: -0.10712218270320671,\n",
       " 497: 0.02837926210216052,\n",
       " 498: 0.5424939854016194,\n",
       " 499: 0.3265677282711354,\n",
       " 500: -0.2661717247084739,\n",
       " 501: -0.3021086139987178,\n",
       " 502: -0.0818509693786091,\n",
       " 503: -0.18255023595796366,\n",
       " 504: 0.31194613239886915,\n",
       " 505: 0.6608559115238953,\n",
       " 506: -0.24196713523215768,\n",
       " 507: -0.14661401451815945,\n",
       " 508: -1.3608543503138253,\n",
       " 509: -0.28873885291072515,\n",
       " 510: -0.6106712037235723,\n",
       " 511: 0.6032823829012044,\n",
       " 512: 0.2606452590714276,\n",
       " 513: 0.3499611210438225,\n",
       " 514: -0.19961473970261612,\n",
       " 515: 1.3011722257770246,\n",
       " 516: 0.17255017124087163,\n",
       " 517: -1.1220068284347768,\n",
       " 518: 0.039122399371863036,\n",
       " 519: 0.8072953014555907,\n",
       " 520: 0.3708107679101926,\n",
       " 521: 0.09916219562463584,\n",
       " 522: 0.3094517529904101,\n",
       " 523: 1.173899055396762,\n",
       " 524: -0.0531884395692883,\n",
       " 525: 0.032500190462475764,\n",
       " 526: 0.6649630164782343,\n",
       " 527: 0.6097413251077474,\n",
       " 528: -0.053494687558900716,\n",
       " 529: -0.29937830904662704,\n",
       " 530: 0.2663662807397043,\n",
       " 531: 0.24453225639506476,\n",
       " 532: 0.7422395897873552,\n",
       " 533: 0.8558730137961226,\n",
       " 534: 0.3012613940270945,\n",
       " 535: -0.8388220260830341,\n",
       " 536: -0.11385787518060823,\n",
       " 537: 0.5428777450811554,\n",
       " 538: 0.958559165929427,\n",
       " 539: 0.28472764048768057,\n",
       " 540: 0.4759756751973683,\n",
       " 541: -0.11773360931437801,\n",
       " 542: -0.005797127566702341,\n",
       " 543: 0.9425287734003214,\n",
       " 544: 0.8605448393398002,\n",
       " 545: -0.12636937181334665,\n",
       " 546: -0.06810585932251811,\n",
       " 547: 0.6291745544323212,\n",
       " 548: 0.5704025187696232,\n",
       " 549: 0.09707313103239926,\n",
       " 550: 0.577816665333434,\n",
       " 551: 0.19571629372902866,\n",
       " 552: -0.3873930873344972,\n",
       " 553: 0.8159516622621712,\n",
       " 554: 0.48309831828848043,\n",
       " 555: -0.04814665003207202,\n",
       " 556: 0.5664138809096952,\n",
       " 557: 0.31940478518385246,\n",
       " 558: 0.41845089469811964,\n",
       " 559: -0.21664082867717377,\n",
       " 560: 0.058284293122298124,\n",
       " 561: -0.13734273611573247,\n",
       " 562: 0.5781489669238463,\n",
       " 563: -0.203755200048836,\n",
       " 564: 0.07502035543200776,\n",
       " 565: 0.13228498314300782,\n",
       " 566: 0.029496297441569494,\n",
       " 567: -1.2611622459947702,\n",
       " 568: 0.6047713734418453,\n",
       " 569: 0.4894727609000262,\n",
       " 570: -0.10075025657424344,\n",
       " 571: -0.931071001640705,\n",
       " 572: 0.6035709826257997,\n",
       " 573: 0.698650595284111,\n",
       " 574: 0.44100744529483243,\n",
       " 575: -0.3399160628951927,\n",
       " 576: -0.40053692747753117,\n",
       " 577: 0.04961633607633705,\n",
       " 578: 0.4609419791370677,\n",
       " 579: 0.4648929370220103,\n",
       " 580: 0.01777482389559464,\n",
       " 581: 0.8322751260545942,\n",
       " 582: 0.5030119501004882,\n",
       " 583: -0.2142899529309203,\n",
       " 584: 0.6073745339121013,\n",
       " 585: 0.8129159859260173,\n",
       " 586: 0.8533592005160117,\n",
       " 587: 0.46910742282846435,\n",
       " 588: -0.2684017927449398,\n",
       " 589: 0.5094251629787878,\n",
       " 590: -0.15162552458461753,\n",
       " 591: -0.2326989517744047,\n",
       " 592: 0.08396324876476446,\n",
       " 593: -0.25789347127207235,\n",
       " 594: 0.4223941465749174,\n",
       " 595: 0.6932969981910384,\n",
       " 596: -0.014341025233106352,\n",
       " 597: 0.4696669695632876,\n",
       " 598: 0.2849077654757039,\n",
       " 599: -0.8606896716891452,\n",
       " 600: -0.5138174754267826,\n",
       " 601: 0.896530975870752,\n",
       " 602: -0.11478108649036158,\n",
       " 603: 0.002059776829497566,\n",
       " 604: -0.018911601946430077,\n",
       " 605: -0.29471041238482365,\n",
       " 606: 0.15123411005715617,\n",
       " 607: 0.27513644248730074,\n",
       " 608: -0.3690799407496264,\n",
       " 609: -0.24606919749206224,\n",
       " 610: 0.18348963600440554}"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bu"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4.673564159871087"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict(1, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
